/**
 * 最终稳定版：从 stats + flatGroupMap + numberGroupMap 精选 32 个号码
 * 若杀组后不足 32 个，则从剩余分组继续补足，确保不会中断
 *
 * @param {Array} stats - item.stats [{ key, value }]
 * @param {Object} flatGroupMap - { groupName => number[][] }
 * @param {Object} numberGroupMap - { number => { groupName: subIndex } }
 * @param {string} lastNumber - 上一期开奖号码（"01" ~ "49"）
 * @param {Object} [opts] - { topN?: number }
 * @returns {string[]} - 最终 32 个不重复两位字符串号码
 */
function select32Numbers(
  stats,
  flatGroupMap,
  numberGroupMap,
  lastNumber,
  opts = {}
) {
  const initialTopN = opts.topN ?? 30;
  const step = 20;
  const maxTopN = 1000;

  const triedNumbers = new Set();
  // let candidateSet = new Set();
  // ✅ 改为：
  let candidateSet = null;

  for (let topN = initialTopN; topN <= maxTopN; topN += step) {
    // candidateSet.clear();
    candidateSet = new Set();

    // const filteredStats = stats
    //   .filter((s) => s?.value?.lastKillCorrect === 1)
    //   .sort((a, b) => {
    //     const va = a.value;
    //     const vb = b.value;

    //     const scoreA =
    //       va.score * 0.6 +
    //       va.accuracyRate * 0.2 +
    //       va.currentConsecutiveCorrect * 0.1 -
    //       va.volatilityScore * 0.1;

    //     const scoreB =
    //       vb.score * 0.6 +
    //       vb.accuracyRate * 0.2 +
    //       vb.currentConsecutiveCorrect * 0.1 -
    //       vb.volatilityScore * 0.1;

    //     return scoreB - scoreA;
    //   })
    //   .slice(0, topN);

    // const filteredStats = stats
    //   .filter((s) => {
    //     const v = s?.value;
    //     if (!v) return false;

    //     // 🚫 新增过滤条件：避免使用短期连续错误严重的分组
    //     const maxAllowConsecutiveIncorrect =
    //       opts.maxAllowConsecutiveIncorrect ?? 3;

    //     if (v.currentConsecutiveIncorrect >= maxAllowConsecutiveIncorrect) {
    //       return false;
    //     }

    //     // ✅ 依旧要求最近杀对
    //     return v.lastKillCorrect === 1;
    //   })
    //   .sort((a, b) => {
    //     const va = a.value;
    //     const vb = b.value;

    //     const scoreA =
    //       va.score * 0.6 +
    //       va.accuracyRate * 0.2 +
    //       va.currentConsecutiveCorrect * 0.1 -
    //       va.volatilityScore * 0.1;

    //     const scoreB =
    //       vb.score * 0.6 +
    //       vb.accuracyRate * 0.2 +
    //       vb.currentConsecutiveCorrect * 0.1 -
    //       vb.volatilityScore * 0.1;

    //     return scoreB - scoreA;
    //   })
    //   .slice(0, topN);

    const maxRecentErrorRate = 0.6; // 最近10期超过6错，淘汰
    const maxCurrentError = 2; // 当前连续错超过2，淘汰

    const filteredStats = stats
      .filter((s) => {
        const v = s?.value;
        if (!v) return false;

        // ⚠️ 连错过滤
        if (v.currentConsecutiveIncorrect > maxCurrentError) return false;

        // ⚠️ 短期密集错误过滤（近10期错误率过高）
        const recentErrorRate = 1 - v.last10AccuracyRate;
        if (recentErrorRate > maxRecentErrorRate) return false;

        // ✅ 最后一次是否杀对（可选保守）
        if (v.lastKillCorrect !== 1) return false;

        return true;
      })
      .sort((a, b) => {
        const va = a.value;
        const vb = b.value;

        const scoreA =
          va.score * 0.6 +
          va.accuracyRate * 0.2 +
          va.currentConsecutiveCorrect * 0.1 -
          va.volatilityScore * 0.1;

        const scoreB =
          vb.score * 0.6 +
          vb.accuracyRate * 0.2 +
          vb.currentConsecutiveCorrect * 0.1 -
          vb.volatilityScore * 0.1;

        return scoreB - scoreA;
      })
      .slice(0, topN);

    filteredStats.forEach(({ key: groupName }) => {
      const group = flatGroupMap[groupName];
      if (!group) return;

      const killIndex = numberGroupMap[lastNumber]?.[groupName];

      group.forEach((subgroup, index) => {
        if (index === killIndex) return; // 杀掉上一期
        subgroup.forEach((n) =>
          candidateSet.add(n.toString().padStart(2, "0"))
        );
      });
    });

    const candidateArray = Array.from(candidateSet);

    if (candidateArray.length >= 32) {
      return candidateArray.slice(0, 32);
    }
  }

  // ⚠️ 如果执行完上面依然没选够，就直接从 flatGroupMap 中全量补充
  for (const [groupName, subGroups] of Object.entries(flatGroupMap)) {
    subGroups.forEach((group) => {
      group.forEach((n) => {
        const padded = n.toString().padStart(2, "0");
        if (!candidateSet.has(padded)) {
          candidateSet.add(padded);
        }
      });
    });

    if (candidateSet.size >= 32) break;
  }

  const final = Array.from(candidateSet).slice(0, 32);

  // 兜底机制，理论上不会再触发
  if (final.length < 32) {
    for (let i = 1; i <= 49 && final.length < 32; i++) {
      const padded = i.toString().padStart(2, "0");
      if (!candidateSet.has(padded)) {
        final.push(padded);
      }
    }
  }

  if (final.length < 32) {
    throw new Error(
      `[select32Numbers] ❌ 最终选出的号码不足 32 个，只得到了 ${final.length} 个，已尝试 ${maxTopN} 个分组`
    );
  }
  return final;
}

module.exports = select32Numbers;
